using System.Configuration;
using Microsoft.Practices.Unity;
using System.Collections.Generic;
using System;

namespace CommonPatterns.IoC
{
    /// <summary>
    /// Extension methods containing some helpers for a IoC container 
    /// </summary>
    public static class UnityContainerExt
    {
        /// <summary>
        /// registers a configuration section locate in the current directory
        /// </summary>
        /// <typeparam name="TConfig"></typeparam>
        /// <typeparam name="Config"></typeparam>
        /// <param name="container"></param>
        /// <param name="fileName"></param>
        public static void FindAndRegisterConfigurationSection<TConfig, Config>(this IUnityContainer container, string fileName)
            where Config : class, TConfig
        {
            var map = new ExeConfigurationFileMap {ExeConfigFilename = fileName};
            Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
            var configurationSection = config.GetSection(typeof (Config).Name) as Config;
            container.RegisterInstance<TConfig>(configurationSection);
        }

        /// <summary> 
        /// BE AWARE !!
        /// return all instances in the IoC that their registration key implements the interface TInterface
        /// </summary>
        /// <typeparam name="TInterface"></typeparam>
        /// <param name="container"></param>
        /// <returns></returns>
        public static IEnumerable<TInterface> FindAllImplementation<TInterface>(this IUnityContainer container)
            where TInterface : class
        {
            foreach (var registration in container.Registrations)
            {
                var key = registration.RegisteredType;
                Type interfaceType = typeof(TInterface);
                if(key == interfaceType || key.GetInterface(interfaceType.Name) != null)
                    yield return container.Resolve(key) as TInterface;
            }
        }

        /// <summary>
        /// return all instances in the IoC that their registration key implements the interface TInterface under the same 
        /// application module
        /// </summary>
        /// <typeparam name="TInterface"></typeparam>
        /// <typeparam name="TModule">application module</typeparam>
        /// <param name="container"></param>
        /// <returns></returns>
        public static IEnumerable<TInterface> FindAllImplementation<TInterface, TModule>(this IUnityContainer container)
            where TInterface : class
            where TModule : IModule
        {
            foreach (var element in container.FindAllImplementation<TInterface>())
            {
                if (element.GetType().Namespace.StartsWith(typeof(TModule).Namespace, StringComparison.OrdinalIgnoreCase))
                    yield return element;
            }
        }
    }
}